package com.bestom.t9mod.core.api;

import android.util.Log;
import android.widget.Toast;

import com.bestom.t9mod.base.SerialApi;
import com.bestom.t9mod.base.manager.Serial.SerialManager;
import com.bestom.t9mod.commons.constant.Const;
import com.bestom.t9mod.commons.constant.KPACmdCode;
import com.bestom.t9mod.commons.constant.KPARECmdCode;
import com.bestom.t9mod.commons.constant.StatusCode;
import com.bestom.t9mod.commons.exceptions.SerialException;
import com.bestom.t9mod.commons.listener.ParseCallback;
import com.bestom.t9mod.commons.listener.RespSampleListener;
import com.bestom.t9mod.commons.utils.DataTurn;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static com.bestom.t9mod.commons.constant.Const.wakeflag;
import static com.bestom.t9mod.commons.constant.KPAErrorCode.*;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_CHECK;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_ERROR;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_INFO;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_PREPARE;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_RESULT;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_SLEEP;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_START;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_STOP;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_VERSION;
import static com.bestom.t9mod.commons.constant.KPARECmdCode.KPA_RECMD_WAKEUP;

public class kPaApi extends SerialApi {
    private static final String TAG = "kPaApi 血压计 --->";
    private CountDownLatch mCountDownLatch;
    private DataTurn DataTurn =new DataTurn();

    private void SCmds(final KPACmdCode kpaCmdCode, final String body , final RespSampleListener listener) {
        //发送指令
        String cmd= jointCmd(kpaCmdCode, body);
        Log.d(TAG, "SCmds: --> cmd：" + cmd);
        try {
            SerialManager.getInstance().sendHex(cmd);
            switch (kpaCmdCode){
                case KPA_CMD_WAKEUP:
                    this.RegisterReplayListener(KPA_RECMD_WAKEUP,listener);
                    break;
                case KPA_CMD_SLEEP:
                    this.RegisterReplayListener(KPA_RECMD_SLEEP,listener);
                    break;
                case KPA_CMD_PREPARE:
                    this.RegisterReplayListener(KPA_RECMD_PREPARE,listener);
                    break;
                case KPA_CMD_START:
                    this.RegisterReplayListener(KPA_RECMD_START,listener);
                    break;
                case KPA_CMD_STOP:
                    this.RegisterReplayListener(KPA_RECMD_STOP,listener);
                    break;
                case KPA_CMD_CHECK:
                    this.RegisterReplayListener(KPA_RECMD_CHECK,listener);
                    break;
                case KPA_CMD_VERSION:
                    this.RegisterReplayListener(KPA_RECMD_VERSION,listener);
                    break;
                default:
                        break;
            }
        } catch (SerialException e) {
            listener.onFailure(StatusCode.SERIAL_ERR.getCode(), e.getMessage());
            Log.e(TAG, e.getMessage());
            return;
        }
    }

    private void sendHex(String hex){
        try {
            SerialManager.getInstance().sendHex(hex);
            Log.d(TAG, "sendHex: 0000,waite time out ");
        } catch (SerialException e) {
            Log.e(TAG, "sendHex: "+hex+" error :"+e.getMessage() );
            e.printStackTrace();
        }
    }

    private void RegisterReplayListener(final KPARECmdCode kpareCmdCode, final RespSampleListener listener) {
        // 注册自动移除观察者
        registerAndRemoveObserver(kpareCmdCode, Const.DEF_TIMEOUT, listener, new ParseCallback() {
            @Override
            public void result(String data) {
                switch (kpareCmdCode){
                    case KPA_RECMD_PREPARE:
                    case KPA_RECMD_START:
                    case KPA_RECMD_STOP:
                    case KPA_RECMD_CHECK:
                        //这几个指令没有body msg
                        break;
                    case KPA_RECMD_VERSION:
                        //处理version 数据
                        String msg = DataTurn.HexToStr(data);
                        listener.onSuccess(StatusCode.SUCCESS.getCode(),msg);
                        break;
                    default:
                        break;
                }
            }
        });
    }

    private void RegisterOnReplayListener(final KPARECmdCode kpareCmdCode, final RespSampleListener<Map<String, String>> listener) {
        // 注册自动移除观察者
        noTimeregisterObserver(kpareCmdCode, listener, new ParseCallback() {
            @Override
            public void result(String data) {
                Log.d(TAG, "result: "+data);
                switch (kpareCmdCode){
                    case KPA_RECMD_INFO:
                        Map<String, String> infomap=new HashMap<>();
                        infomap.put("MSB", String.valueOf(Integer.parseInt(data.substring(0,2),16)));
                        infomap.put("LSB",String.valueOf(Integer.parseInt(data.substring(2,4),16)));
                        listener.onSuccess(StatusCode.SUCCESS.getCode(),infomap);
                        break;
                    case KPA_RECMD_RESULT:
                        Map<String, String> resultmap=new HashMap<>();
                        resultmap.put("SYS_MSB",String.valueOf(Integer.parseInt(data.substring(0,2),16)));
                        resultmap.put("SYS_LSB",String.valueOf(Integer.parseInt(data.substring(2,4),16)));
                        resultmap.put("DIA_MSB",String.valueOf(Integer.parseInt(data.substring(4,6),16)));
                        resultmap.put("DIA_LSB",String.valueOf(Integer.parseInt(data.substring(6,8),16)));
                        resultmap.put("PLUSE",String.valueOf(Integer.parseInt(data.substring(8,10),16)));
                        listener.onSuccess(StatusCode.SUCCESS.getCode(),resultmap);
                        break;
                    case KPA_RECMD_ERROR:
                        //FF FE 05 7D 56 01
                        Map<String, String> errormap=new HashMap<>();
                        int errorcode = DataTurn.HexToInt(data.substring(0,2));
                        String errormsg = "";
                        switch (errorcode){
                            case 0:
                                errormsg= ERROR0.getMsg();
                            case 1:
                                errormsg= ERROR1.getMsg();
                                break;
                            case 2:
                                errormsg= ERROR2.getMsg();
                                break;
                            case 3:
                                errormsg= ERROR3.getMsg();
                                break;
                            case 4:
                                errormsg= ERROR4.getMsg();
                                break;
                            default:
                                break;
                        }
                        errormap.put("ERROR_CODE", String.valueOf(errorcode));
                        errormap.put("ERROR_MSG",errormsg);
                        listener.onSuccess(StatusCode.SUCCESS.getCode(),errormap);
                        break;
                    default:
                        break;
                }
            }
        });
    }

    public void RemoveOnListener(KPARECmdCode kpareCmdCode){
        removeObserver(kpareCmdCode);
    }

    public void wakeup(final RespSampleListener listener){
        /*try {
            mCountDownLatch=new CountDownLatch(1);
            this.sendHex(wakeflag);
            mCountDownLatch.await(1, TimeUnit.SECONDS);
            Log.d(TAG, "wakeup: mCountDownLatch doing send cmd ");
            this.SCmds(KPACmdCode.KPA_CMD_WAKEUP,"",listener);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/

        this.sendHex(wakeflag);
        try {
            Thread.sleep(60);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "wakeup: mCountDownLatch doing send cmd ");
            this.SCmds(KPACmdCode.KPA_CMD_WAKEUP,"",listener);

    }

    public void sleep(final RespSampleListener listener){
        this.SCmds(KPACmdCode.KPA_CMD_SLEEP,"",listener);
    }

    public void prepare(final RespSampleListener listener){
        this.SCmds(KPACmdCode.KPA_CMD_PREPARE,"",listener);
    }

    public void start(final RespSampleListener listener){
        this.SCmds(KPACmdCode.KPA_CMD_START,"",listener);
    }

    public void stop(final RespSampleListener listener){
        this.SCmds(KPACmdCode.KPA_CMD_STOP,"",listener);
    }

    public void check(final RespSampleListener listener){
        this.SCmds(KPACmdCode.KPA_CMD_CHECK,"",listener);
    }

    public void version(final RespSampleListener listener){
        this.SCmds(KPACmdCode.KPA_CMD_VERSION,"",listener);
    }

    public void onInfo(final RespSampleListener<Map<String, String>> listener){
        this.RegisterOnReplayListener(KPA_RECMD_INFO,listener);
    }

    public void onResult(final RespSampleListener<Map<String, String>> listener){
        this.RegisterOnReplayListener(KPA_RECMD_RESULT,listener);
    }

    public void onError(final RespSampleListener<Map<String, String>> listener){
        this.RegisterOnReplayListener(KPA_RECMD_ERROR,listener);
    }

    public void Release(){
        ClearObserver();
    }


}
